package io.gitee.vexlife.snakeagentexample.astar;

import java.util.LinkedList;

import io.gitee.vexlife.snake.GameController;
import io.gitee.vexlife.snake.IAgent;
import io.gitee.vexlife.snake.SnakeAgent;
import io.gitee.vexlife.snakeagentexample.astar.AStar;
import io.gitee.vexlife.snake.basic.Direction;
import io.gitee.vexlife.snake.basic.Node;

@SnakeAgent(name="A*算法玩家", description = "这是一个示例引擎，它是基于A*算法的人工智能贪吃蛇玩家。")
public class AStarPlayer implements IAgent {

	private GameController gmctrl;

	@Override
	public void step() {
		AStar searcher = new AStar();
		Direction decision = searcher.AStarSearch(this.gmctrl.getSnake().getHead(), this.gmctrl.getFood().getFoodNode(),
				this.gmctrl, false, true);
		boolean flag = true;
		if (decision != null) {
			LinkedList<Node> bak = (LinkedList<Node>) this.gmctrl.getSnake().getNodes().clone();
			LinkedList<Node> now = this.gmctrl.getSnake().getNodes();
			for (int i = searcher.getTrace().size() - 2; i >= 0; i--) {
				if (i != 0)
					now.removeFirst();
				now.add(searcher.getTrace().get(i));
			}
			searcher.clearTrace();
			flag = searcher.AStarSearch(this.gmctrl.getFood().getFoodNode(), this.gmctrl.getSnake().getTail(),
					this.gmctrl, false, true) != null;
			this.gmctrl.getSnake().setNodes(bak);
			flag = flag && searcher.AStarSearch(this.gmctrl.getSnake().getHead(), this.gmctrl.getFood().getFoodNode(),
					this.gmctrl, false, false) != null;
			if (!flag) {
				searcher.clearTrace();
				decision = searcher.AStarSearch(this.gmctrl.getSnake().getHead(), this.gmctrl.getFood().getFoodNode(),
						this.gmctrl, false, false);
				bak = (LinkedList<Node>) this.gmctrl.getSnake().getNodes().clone();
				now = this.gmctrl.getSnake().getNodes();
				for (int i = searcher.getTrace().size() - 2; i >= 0; i--) {
					if (i != 0)
						now.removeFirst();
					now.add(searcher.getTrace().get(i));
				}
				searcher.clearTrace();
				flag = searcher.AStarSearch(this.gmctrl.getFood().getFoodNode(), this.gmctrl.getSnake().getTail(),
						this.gmctrl, false, true) != null;
				this.gmctrl.getSnake().setNodes(bak);
				flag = flag && searcher.AStarSearch(this.gmctrl.getSnake().getHead(),
						this.gmctrl.getFood().getFoodNode(), this.gmctrl, false, false) != null;
			}
		}
		if (decision == null || !flag) {
			decision = searcher.wander(this.gmctrl.getSnake().getHead(), this.gmctrl.getFood().getFoodNode(),
					this.gmctrl);
		}
		this.gmctrl.getSnake().setDirection(decision);
	}

	@Override
	public void initAgent(GameController gmctrl) {
		this.gmctrl = gmctrl;
	}

}